package com.qiguliuxing.dts.job.task;

import com.dangdang.ddframe.job.api.ShardingContext;
import com.dangdang.ddframe.job.api.simple.SimpleJob;
import com.google.common.collect.Maps;
import com.qiguliuxing.dts.common.constant.CommConsts;
import com.qiguliuxing.dts.common.constant.RedisKeyConsts;
import com.qiguliuxing.dts.core.manager.HomeCacheManager;
import com.qiguliuxing.dts.db.domain.DtsCategory;
import com.qiguliuxing.dts.db.domain.DtsGoods;
import com.qiguliuxing.dts.service.base.*;
import com.qiguliuxing.dts.service.seckill.WxSeckillService;
import com.qiguliuxing.dts.service.system.SystemConfig;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

import static org.slf4j.LoggerFactory.getLogger;

/**
 * 首页缓存数据的加载
 * @author qiguliuxing
 * @since 1.0.0
 */
@Component
public class IndexDataJob implements SimpleJob {
    private static final Logger logger = getLogger(IndexDataJob.class);

    @Autowired
    private DtsAdService adService;

    @Autowired
    private DtsGoodsService goodsService;

    @Autowired
    private DtsBrandService brandService;

    @Autowired
    private DtsTopicService topicService;

    @Autowired
    private DtsCategoryService categoryService;

    @Autowired
    private DtsGrouponRulesService grouponRulesService;

    @Autowired
    private DtsArticleService articleService;

    @Autowired
    private WxSeckillService wxSeckillService;


    /**
     * 执行作业.
     *
     * @param shardingContext 分片上下文
     */
    @Override
    public void execute(ShardingContext shardingContext) {
        logger.info(String.format("Thread ID: %s, 作业分片总数: %s, " +
                        "当前分片项: %s.当前参数: %s," +
                        "作业名称: %s.作业自定义参数: %s",
                Thread.currentThread().getId(),
                shardingContext.getShardingTotalCount(),
                shardingContext.getShardingItem(),
                shardingContext.getShardingParameter(),
                shardingContext.getJobName(),
                shardingContext.getJobParameter()
        ));

        Map<String, Object> paramsMap = Maps.newHashMapWithExpectedSize(CommConsts.INIT_HASH_MAP_SIZE);
        paramsMap.put("shardingTotalCount", shardingContext.getShardingTotalCount());
        paramsMap.put("shardingItem", shardingContext.getShardingItem());

        ExecutorService executorService = Executors.newFixedThreadPool(10);
        try {
            Map<String, Object> data = Maps.newHashMapWithExpectedSize(7);
            Callable<List> bannerListCallable = () -> adService.queryIndex();
            Callable<List> articleListCallable = () -> articleService.queryList(0, 5, "add_time", "desc");
            Callable<List> channelListCallable = () -> categoryService.queryChannel();
            Callable<List> newGoodsListCallable = () -> goodsService.queryByNew(0, SystemConfig.getNewLimit());
            Callable<List> hotGoodsListCallable = () -> goodsService.queryByHot(0, SystemConfig.getHotLimit());
            Callable<List> brandListCallable = () -> brandService.queryVO(0, SystemConfig.getBrandLimit());
            Callable<List> topicListCallable = () -> topicService.queryList(0, SystemConfig.getTopicLimit());
            // 团购专区
            Callable<List> grouponListCallable = () -> grouponRulesService.queryList(0, 6);
            Callable<List> floorGoodsListCallable = this::getCategoryList;
            FutureTask<List> bannerTask = new FutureTask<>(bannerListCallable);
            FutureTask<List> articleTask = new FutureTask<>(articleListCallable);
            FutureTask<List> channelTask = new FutureTask<>(channelListCallable);
            FutureTask<List> newGoodsListTask = new FutureTask<>(newGoodsListCallable);
            FutureTask<List> hotGoodsListTask = new FutureTask<>(hotGoodsListCallable);
            FutureTask<List> brandListTask = new FutureTask<>(brandListCallable);
            FutureTask<List> topicListTask = new FutureTask<>(topicListCallable);
            FutureTask<List> grouponListTask = new FutureTask<>(grouponListCallable);
            FutureTask<List> floorGoodsListTask = new FutureTask<>(floorGoodsListCallable);

            executorService.submit(bannerTask);
            executorService.submit(articleTask);
            executorService.submit(channelTask);
            executorService.submit(newGoodsListTask);
            executorService.submit(hotGoodsListTask);
            executorService.submit(brandListTask);
            executorService.submit(topicListTask);
            executorService.submit(grouponListTask);
            executorService.submit(floorGoodsListTask);

            data.put("banner", bannerTask.get());
            data.put("articles", articleTask.get());
            data.put("channel", channelTask.get());
            data.put("newGoodsList", newGoodsListTask.get());
            data.put("hotGoodsList", hotGoodsListTask.get());
            data.put("brandList", brandListTask.get());
            data.put("topicList", topicListTask.get());
            data.put("grouponList", grouponListTask.get());
            data.put("floorGoodsList", floorGoodsListTask.get());
            data.put("seckillGoodsList", wxSeckillService.getCurrBatchSeckillGood(null,0,SystemConfig.getSeckillLimit()));
            // 缓存数据首页缓存数据
            HomeCacheManager.loadData(RedisKeyConsts.HOME_CACHE_INDEX, data);
            logger.info("首页缓存数据成功加载...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        } finally {
            executorService.shutdown();
        }
    }

    private List<Map> getCategoryList() {
        List<Map> categoryList = new ArrayList<>();
        List<DtsCategory> catL1List = categoryService.queryL1WithoutRecommend(0, SystemConfig.getCatlogListLimit());
        for (DtsCategory catL1 : catL1List) {
            List<DtsCategory> catL2List = categoryService.queryByPid(catL1.getId());
            List<Integer> l2List = new ArrayList<>();
            for (DtsCategory catL2 : catL2List) {
                l2List.add(catL2.getId());
            }

            List<DtsGoods> categoryGoods;
            if (l2List.size() == 0) {
                categoryGoods = new ArrayList<>();
            } else {
                categoryGoods = goodsService.queryByCategory(l2List, 0, SystemConfig.getCatlogMoreLimit());
            }

            Map<String, Object> catGoods = Maps.newHashMapWithExpectedSize(7);
            catGoods.put("id", catL1.getId());
            catGoods.put("name", catL1.getName());
            catGoods.put("goodsList", categoryGoods);
            categoryList.add(catGoods);
        }
        return categoryList;
    }
}
